#pragma once

#include "HSModelAPI.h"
#include "ModelEvents.h"

class Ground;
class WorldObject;
/**
*  Class which represents all game logic
*/
class GameController
  {
  public:
    HSMODEL_API GameController();
    
    HSMODEL_API int GetMoney() const;
    HSMODEL_API void SetMoney(int i_money);
    HSMODEL_API void SetHumanCount(size_t i_human_count);

    HSMODEL_API double GetHappiness() const;

    HSMODEL_API bool CanPlaceTree() const;
    HSMODEL_API bool CanCreateWalkway() const;
    HSMODEL_API bool CanCreateWater() const;
    HSMODEL_API bool CanCreateGrass() const;
    HSMODEL_API bool CanPlaceBalloonsShop() const;
    HSMODEL_API bool CanPlaceBench() const;
    
    HSMODEL_API void FerrisWheelPlaced(bool i_pay_money = true);
    HSMODEL_API void BalloonsShopPlaced(bool i_pay_money = true);
    HSMODEL_API void TreePlaced(bool i_pay_money = true);
    HSMODEL_API void BenchPlaced(bool i_pay_money = true);
    HSMODEL_API void WalkwayCreated(bool i_pay_money = true);
    HSMODEL_API void GrassAdded(bool i_walkway_deleted = false, bool i_pay_money = true);

    HSMODEL_API void WalkwayDeleted();
    HSMODEL_API void ObjectDestroyed(WorldObject* ip_object);

    HSMODEL_API void WaterCreated(bool i_pay_money = true);
    HSMODEL_API void WaterRemoved();

    HSMODEL_API void LandscapeChanged(const Ground& i_ground);

    HSMODEL_API void SubscribeOnValuesChangedEvent(Observer i_callback) const;
    HSMODEL_API void SubscribeOnHumanCountChangedEvent(Observer i_callback) const;

    HSMODEL_API void Reset();

    HSMODEL_API void MakeProfit();
  private:
    void _GenerateAllEvents() const;

    double _CalculateLandscapeBeauty(const Ground& i_ground) const;
    size_t _RecalculateHumanCount() const;

  protected:
    size_t m_water_count;

  private:
    int m_money;
    size_t m_tree_count;
    size_t m_walkway_count;
    size_t m_ferris_wheel_count;
    size_t m_balloons_shop_count;
    size_t m_human_count;
    size_t m_bench_count;
    double m_landscape_beauty;

    mutable SimpleEvent m_values_changed_event;
    mutable SimpleEvent m_human_count_changed_event;
  };

